package com.aispeech.task.lasr.event;

import com.aispeech.task.common.data.domain.Task;
import com.aispeech.task.common.exceptions.TaskException;
import com.aispeech.task.constant.LASRProgress;
import com.aispeech.task.fsm.Event;
import com.aispeech.task.lasr.LASREventType;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

import static com.aispeech.task.lasr.LASRTaskHandler.updateTaskStatus;

@Slf4j
public class FuseEvent extends Event<Task> {
    private static final int STEP = 10;

    List<JsonNode> asrResList;

    public FuseEvent(Task task, List<JsonNode> asrResList) {
        super(LASREventType.Asred, task);
        this.asrResList = asrResList;
    }

    @Override
    public Event fire() {
        Task task = this.getTarget();
        Event nextEvent;

        try {
            updateTaskStatus(task, LASRProgress.FUSE, "ts_fuse");

            Thread.sleep(1000L);

            List<Map> result = new ArrayList<>();
            Random random = new Random();

            for (int i = 0; i < asrResList.size(); i++) {
                int current = i + STEP;

                int finalI = i;
                result.add(
                        new HashMap() {{
                            put("bg", current);
                            put("ed", current + 10);
                            put("audio", asrResList.get(finalI).path("audio").asText());
                            put("onebest", asrResList.get(finalI).path("rec").asText());
                            put("random", (int) (current + Math.floor(random.nextDouble() * STEP)));
                        }});
            }

            int taskType = (int) task.getRequest().getOrDefault("task_type", 1);
            if (taskType > 1) {
                task.setResult(result);
                nextEvent = new LabelEvent(task);
            } else {
                nextEvent = new FinishEvent(LASREventType.Fused, task, result);
            }

            updateTaskStatus(task, LASRProgress.FUSED, "ts_fused");
        } catch (InterruptedException | TaskException ex) {
            nextEvent = new ErrorEvent(task);
        }

        return nextEvent;
    }
}
